package optimization.evolution;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Random;
import optimization.AbstractOptimizationAlgorithm;
import automaton.AutomatonMetaData;
import automaton.efsm.DefiniteEFSM;

public class EvolutionOptimizationAlgorithm extends AbstractOptimizationAlgorithm {
	private static Random random = new Random();
	
	public EvolutionOptimizationAlgorithm() {
		
	}
	
    public DefiniteEFSM findBestMutatedDFA(AutomatonMetaData dfaMetaData) {
    	DefiniteEFSM dfa = dfaMetaData.getDFA();
        AutomatonMetaData mutatedAutomatas[] = new AutomatonMetaData[dfa.getNumberOfTransitions()];
        int transitionCounter = 0;
        for (int i = 0; i < dfa.getNumberOfStates(); i++) {
            for (int j = 0; j < dfa.getNumberOfExternalInfluences(); j++) {
                if (dfa.transitions[i][j].getEndState() == -1) { 
                    continue;
                }
                DefiniteEFSM mutatedDFA = mutateDFA(dfa, i, j);
                mutatedAutomatas[transitionCounter++] = task.getFitness(mutatedDFA);
            }
        }
        
        Arrays.sort(mutatedAutomatas, new Comparator<AutomatonMetaData>() {

			@Override
			public int compare(AutomatonMetaData arg0, AutomatonMetaData arg1) {
				if (arg0.getFitness() > arg1.getFitness()) {
					return 1;
				}
				return 0;
			}
        });
        
        if (mutatedAutomatas[0].getFitness() > dfaMetaData.getFitness()) {  
        	return mutatedAutomatas[0].getDFA();
        }
        return dfa;
    }
    
    
    public DefiniteEFSM mutateDFA(DefiniteEFSM dfa, int state, int event) {
        DefiniteEFSM result = new DefiniteEFSM(dfa);
        int newState = random.nextInt(dfa.getNumberOfStates());
//        String newAction = task.getActions()[random.nextInt(task.getActions().length)];
//        result.transitions[state][event] = new DFA.Transition(state, newState, newAction);
        return result;
    }


	@Override
	public AutomatonMetaData run() {
		// TODO Auto-generated method stub
		return null;
	}

}
